home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / system / interc2.zip / INTERPRE.C < prev    next >
Text File  |  1987-08-02  |  6KB  |  230 lines

  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <ctype.h>
  4. #include <dos.h>
  5. #include <dir.h>
  6. #include "intercep.h"
  7.  
  8. #define MAXFILESIZE 20000        /* maximum template file size */
  9. #define MAXLINELEN 200            /* maximum output line length */
  10. #define AVGLINELEN 40            /* average line length */
  11.  
  12. char template_text[ MAXFILESIZE ];        /* file text */
  13. char *templates[ MAXFILESIZE/AVGLINELEN ];    /* pointers to each line */
  14. int ntemplates;        /* number of templates */
  15.  
  16. /* copy template to dest, changing regname to regval throughout.
  17.  * assumes dest is big enough to hold result.
  18.  */
  19. void
  20. subst(char *regname, unsigned rval, char *template, char *dest)
  21. {
  22.     char regval[5];
  23.     if (regname[1] == 'H' || regname[1] == 'L')
  24.         sprintf(regval, "%02X", rval);
  25.     else
  26.         sprintf(regval, "%04X", rval);
  27.     while (*dest = *template) { /* copy through '\0' at end of string. */
  28.         if (template[0] == regname[0] && template[1] == regname[1]) {
  29.             dest = stpcpy(dest, regval);
  30.             template += 2;    /* all regnames are 2 chars long */
  31.         }
  32.         else {
  33.             template++;
  34.             dest++;
  35.         }
  36.     }
  37. }
  38.  
  39. /* Read template file into buffer, setting pointers to
  40.  * beginning of lines.
  41.  * Sets template_text, templates and ntemplates.
  42.  * Pads out interrupt IDs to 6 characters.
  43.  * Returns number of lines.
  44.  */
  45. int
  46. read_template_file(char *filename)
  47. {
  48.     FILE *ifile;
  49.     char inline[ MAXLINELEN ];
  50.     char **nextline = templates;
  51.     char *dest = template_text;
  52.     char *q = template_text;
  53.  
  54.     if (! (ifile = fopen(filename, "rt")))
  55.         return 0;
  56.     while (fgets(inline, MAXLINELEN, ifile)) {
  57.         char *p = inline;
  58.         if (! isxdigit(inline[0]))
  59.             continue;    /* handle comment lines */
  60.         *nextline++ = dest = q;
  61.         while (isxdigit(*p))
  62.             *q++ = *p++;    /* copy initial hex string */
  63.         while (q < dest+6)
  64.             *q++ = ' ';        /* pad out to 6 characters */
  65.         *p = ' ';            /* convert tab (or whatever) to space */
  66.         while (*q++ = *p++)
  67.             ;                /* copy rest of line through null */
  68.         while (q[-3] == '\\' && q[-2] == '\n') {    /* continuation lines */
  69.             if (p = fgets(inline, MAXLINELEN, ifile)) {
  70.                 q -= 3;
  71.                 *q++ = '\n';
  72.                 while (*q++ = *p++)
  73.                     ;
  74.             }
  75.             else
  76.                 goto on_eof;
  77.         }
  78.     }
  79. on_eof:
  80.     *nextline = NULL;
  81.     return (ntemplates = nextline - templates);
  82. }
  83.  
  84. int compare_templates(char **t1, char **t2)
  85. {
  86.     return(strnicmp(*t1, *t2, 6));
  87. }
  88.  
  89. /* find a matching template given interrupt number and ax value
  90.  * works from the most specific (all 6 characters)
  91.  * back to the most general (just the 2 characters of the interrupt number).
  92.  */
  93. char *find_template(int intnum, unsigned axval)
  94. {
  95.     char proposed[ 7 ];
  96.     char *key = proposed;
  97.     char **found;
  98.     char *ignoring = proposed + 6;
  99.  
  100.     sprintf(proposed, "%02X%04X", intnum, axval);
  101.  
  102.     while (ignoring > proposed) {
  103.         if (found = bsearch(&key, templates, ntemplates,
  104.             sizeof(char *), compare_templates))
  105.                 return(*found);
  106.         /* else ignore 2 more characters */
  107.         ignoring -= 2;
  108.         ignoring[0] = ignoring[1] = ' ';
  109.     }
  110.     return NULL;
  111. }
  112.  
  113. #define HI(u)    (((u)&0xff00)>>8)
  114. #define LO(u)    ((u)&0x00ff)
  115.  
  116. /* read Swi_info records from input file
  117.  * interpret them, and output to output file.
  118.  */
  119. void
  120. interpret_file(FILE *ifp, FILE *ofp, char *progname, int longmode)
  121. {
  122.     Swi_info rec;
  123.     char s1[ MAXLINELEN ];
  124.     char s2[ MAXLINELEN ];
  125.     char *templ;
  126.  
  127.     if (progname != NULL)
  128.         fprintf (ofp, "INTERCEPT/INTERPRET by Ned Konz 08/02/87\n"
  129.             "dump of DOS/BIOS calls from program \"%s\"\n",
  130.             progname);
  131.     if (longmode)
  132.         fprintf(ofp,
  133.             "  CS:IP   INT  AX    BX   CX   DX    DS   ES   SI   DI   BP\n");
  134.  
  135.     while (fread(&rec, sizeof(Swi_info), 1, ifp)) {
  136.         if (templ = find_template(rec.intnum, rec.regs.ovl.old[2])) {
  137.             subst("AX", rec.regs.ovl.old[2],  templ, s1);
  138.             subst("AH", HI(rec.regs.ovl.old[2]), s1, s2);
  139.             subst("AL", LO(rec.regs.ovl.old[2]), s2, s1);
  140.  
  141.             subst("BX", rec.regs.ovl.old[1],     s1, s2);
  142.             subst("BH", HI(rec.regs.ovl.old[1]), s2, s1);
  143.             subst("BL", LO(rec.regs.ovl.old[1]), s1, s2);
  144.  
  145.             subst("CX", rec.regs.ovl.old[0],     s2, s1);
  146.             subst("CH", HI(rec.regs.ovl.old[0]), s1, s2);
  147.             subst("CL", LO(rec.regs.ovl.old[0]), s2, s1);
  148.  
  149.             subst("DX", rec.regs.dx,         s1, s2);
  150.             subst("DH", HI(rec.regs.dx),     s2, s1);
  151.             subst("DL", LO(rec.regs.dx),     s1, s2);
  152.  
  153.             subst("BP", rec.regs.bp,         s2, s1);
  154.             subst("DI", rec.regs.di,         s1, s2);
  155.             subst("SI", rec.regs.si,         s2, s1);
  156.             subst("DS", rec.regs.ds,         s1, s2);
  157.             subst("ES", rec.regs.es,         s2, s1);
  158.  
  159.             subst("CS", FP_SEG(rec.caller.ipcs),       s1, s2);
  160.             subst("IP", FP_OFF(rec.caller.ipcs),       s2, s1);
  161.             fprintf(ofp, "%Fp  %s",
  162.                 (char far *)rec.caller.ipcs - 2, s1);
  163.         }
  164.  
  165.         if ((templ==NULL) || longmode) {
  166.           fprintf(ofp,
  167.             "%Fp  %2x %04x  "
  168.             "%04x %04x %04x  "
  169.             "%04x %04x %04x %04x %04x\n",
  170.             (char far *)rec.caller.ipcs - 2, rec.intnum,
  171.             rec.regs.ovl.old[2], /*AX*/
  172.             rec.regs.ovl.old[1] /*BX*/, rec.regs.ovl.old[0],/*CX*/ rec.regs.dx,
  173.             rec.regs.ds, rec.regs.es, rec.regs.si, rec.regs.di,
  174.             rec.regs.bp);
  175.         }
  176.     } /*while*/
  177.  
  178.     return;
  179. }
  180.  
  181. int
  182. main(int argc, char *argv[])
  183. {
  184.     int longmode = 0;
  185.     char *templfile = TFILENAME;
  186.     char *progname = argv[0];
  187.     FILE *ifp, *ofp;
  188.  
  189.     if (argc < 3) {
  190.         fprintf(stderr, "INTERCEPT/INTERPRET by Ned Konz 08/02/87\n"
  191.             "usage: %s [-l] [-t templ_file] "
  192.             "infile outfile [progname]\n",
  193.             argv[0]);
  194.         exit(1);
  195.     }
  196.     argv++;
  197.  
  198.     while (argv[0][0] == '-') {
  199.         if (! stricmp(argv[0], "-l")) { longmode++; }
  200.         else if (! stricmp(argv[0], "-t")) { templfile = argv[1]; argv++; }
  201.         else {
  202.             fprintf(stderr, "%s: unknown switch \"%s\"\n", progname, argv[0]);
  203.             exit(4);
  204.         }
  205.         argv++;
  206.     }
  207.  
  208.     if (! read_template_file( searchpath(templfile) )) {
  209.         fprintf(stderr, "%s: error during read of \"%s\"\n",
  210.             progname, templfile);
  211.         exit(5);
  212.     }
  213.     qsort(templates, ntemplates, sizeof(char *), compare_templates);
  214.     if (! (ifp = fopen(argv[0], "rb"))) {
  215.         fprintf(stderr, "%s: can't open input file \"%s\"\n",
  216.             progname, argv[0]);
  217.         exit(2);
  218.     }
  219.     if (! (ofp = fopen(argv[1], "wt"))) {
  220.         fprintf(stderr, "%s: can't open output file \"%s\"\n",
  221.             progname, argv[1]);
  222.         exit(3);
  223.     }
  224.     interpret_file(ifp, ofp, argv[2], longmode);
  225.     fclose(ifp);
  226.     fclose(ofp);
  227.     exit(0);
  228. }
  229.  
  230.